import sys
import shutil
import os
from PySide6.QtWidgets import (QApplication, QMainWindow, QPushButton, QVBoxLayout, 
                             QHBoxLayout, QWidget, QFileDialog, QLabel, QProgressBar,
                             QMessageBox, QFrame)
from PySide6.QtCore import Qt, QThread, Signal
from PySide6.QtGui import QFont

class CopyThread(QThread):
    """复制操作的线程类，避免UI卡顿"""
    progress_updated = Signal(int)
    copy_finished = Signal(bool, str)
    
    def __init__(self, src, dest):
        super().__init__()
        self.src = src
        self.dest = dest
        self.total_files = 0
        self.copied_files = 0
        
    def count_files(self, directory):
        """计算目录中文件的总数，用于进度条"""
        count = 0
        for root, dirs, files in os.walk(directory):
            count += len(files)
        return count
    
    def copy_directory(self, src, dest):
        """递归复制目录及其内容"""
        try:
            # 如果目标目录不存在，则创建
            if not os.path.exists(dest):
                os.makedirs(dest)
            
            # 复制文件
            for item in os.listdir(src):
                s = os.path.join(src, item)
                d = os.path.join(dest, item)
                
                if os.path.isfile(s):
                    shutil.copy2(s, d)  # 复制文件，保留元数据
                    self.copied_files += 1
                    progress = int((self.copied_files / self.total_files) * 100)
                    self.progress_updated.emit(progress)
                elif os.path.isdir(s):
                    self.copy_directory(s, d)  # 递归复制子目录
                    
            return True, "复制完成"
        except Exception as e:
            return False, f"复制失败: {str(e)}"
    
    def run(self):
        """线程执行函数"""
        self.total_files = self.count_files(self.src)
        if self.total_files == 0:
            self.copy_finished.emit(True, "源文件夹为空，无需复制")
            return
            
        success, message = self.copy_directory(self.src, self.dest)
        self.copy_finished.emit(success, message)

class FolderCopyTool(QMainWindow):
    """文件夹复制工具主窗口"""
    def __init__(self):
        super().__init__()
        self.src_path = ""
        self.dest_path = ""
        self.init_ui()
        
    def init_ui(self):
        """初始化UI界面"""
        self.setWindowTitle("文件夹复制工具")
        self.setGeometry(100, 100, 700, 350)
        
        # 创建中心部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        # 主布局
        main_layout = QVBoxLayout(central_widget)
        main_layout.setSpacing(20)
        main_layout.setContentsMargins(30, 30, 30, 30)
        
        # 标题
        title_label = QLabel("文件夹复制工具")
        title_font = QFont()
        title_font.setPointSize(20)
        title_font.setBold(True)
        title_label.setFont(title_font)
        title_label.setAlignment(Qt.AlignCenter)
        main_layout.addWidget(title_label)
        
        # 源文件夹选择
        src_layout = QHBoxLayout()
        self.src_label = QLabel("未选择源文件夹")
        self.src_label.setStyleSheet("color: #666;")
        self.src_btn = QPushButton("选择源文件夹")
        self.src_btn.clicked.connect(self.select_source)
        self.src_btn.setStyleSheet("padding: 8px 16px;")
        src_layout.addWidget(self.src_label, 3)
        src_layout.addWidget(self.src_btn, 1)
        main_layout.addLayout(src_layout)
        
        # 目标文件夹选择
        dest_layout = QHBoxLayout()
        self.dest_label = QLabel("未选择目标文件夹")
        self.dest_label.setStyleSheet("color: #666;")
        self.dest_btn = QPushButton("选择目标文件夹")
        self.dest_btn.clicked.connect(self.select_destination)
        self.dest_btn.setStyleSheet("padding: 8px 16px;")
        dest_layout.addWidget(self.dest_label, 3)
        dest_layout.addWidget(self.dest_btn, 1)
        main_layout.addLayout(dest_layout)
        
        # 分隔线
        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        main_layout.addWidget(line)
        
        # 进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setValue(0)
        self.progress_bar.setStyleSheet("""
            QProgressBar {
                border: 1px solid #ccc;
                border-radius: 4px;
                text-align: center;
                height: 20px;
            }
            QProgressBar::chunk {
                background-color: #4CAF50;
                border-radius: 3px;
            }
        """)
        main_layout.addWidget(self.progress_bar)
        
        # 复制按钮
        self.copy_btn = QPushButton("开始复制")
        self.copy_btn.clicked.connect(self.start_copy)
        self.copy_btn.setStyleSheet("""
            padding: 10px;
            font-size: 16px;
            background-color: #2196F3;
            color: white;
            border: none;
            border-radius: 4px;
        """)
        self.copy_btn.setDisabled(True)
        main_layout.addWidget(self.copy_btn, alignment=Qt.AlignCenter)
        
    def select_source(self):
        """选择源文件夹"""
        folder = QFileDialog.getExistingDirectory(self, "选择源文件夹")
        if folder:
            self.src_path = folder
            self.src_label.setText(f"源文件夹: {folder}")
            self.check_copy_ready()
    
    def select_destination(self):
        """选择目标文件夹"""
        folder = QFileDialog.getExistingDirectory(self, "选择目标文件夹")
        if folder:
            self.dest_path = folder
            self.dest_label.setText(f"目标文件夹: {folder}")
            self.check_copy_ready()
    
    def check_copy_ready(self):
        """检查是否可以开始复制"""
        if self.src_path and self.dest_path and self.src_path != self.dest_path:
            self.copy_btn.setDisabled(False)
        else:
            self.copy_btn.setDisabled(True)
    
    def start_copy(self):
        """开始复制操作"""
        # 检查源文件夹和目标文件夹是否有效
        if not os.path.isdir(self.src_path):
            QMessageBox.warning(self, "警告", "源文件夹不存在或无效")
            return
            
        if not os.path.isdir(self.dest_path):
            QMessageBox.warning(self, "警告", "目标文件夹不存在或无效")
            return
            
        # 检查源文件夹和目标文件夹是否相同
        if os.path.abspath(self.src_path) == os.path.abspath(self.dest_path):
            QMessageBox.warning(self, "警告", "源文件夹和目标文件夹不能相同")
            return
        
        # 创建并启动复制线程
        self.copy_thread = CopyThread(self.src_path, self.dest_path)
        self.copy_thread.progress_updated.connect(self.update_progress)
        self.copy_thread.copy_finished.connect(self.copy_complete)
        self.copy_thread.start()
        
        # 禁用按钮防止重复操作
        self.src_btn.setDisabled(True)
        self.dest_btn.setDisabled(True)
        self.copy_btn.setDisabled(True)
    
    def update_progress(self, value):
        """更新进度条"""
        self.progress_bar.setValue(value)
    
    def copy_complete(self, success, message):
        """复制完成处理"""
        if success:
            QMessageBox.information(self, "提示", message)
        else:
            QMessageBox.critical(self, "错误", message)
        
        # 重置UI状态
        self.progress_bar.setValue(0)
        self.src_btn.setDisabled(False)
        self.dest_btn.setDisabled(False)
        self.check_copy_ready()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = FolderCopyTool()
    window.show()
    sys.exit(app.exec())
    